import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.*;

import org.json.JSONException;

import DataType.MessageFormat;

import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class SocketSender extends Thread {

	private String host;
	private int port;

	SocketSender(String host, int port) {
		this.host = host;
		this.port = port;
	}

	private Socket socket;
	private HeartBeat heartbeat;
	private ArrayList<VirtualSensor> sensors = new ArrayList<VirtualSensor>();
	private ArrayList<ByteBuffer> bufferList = new ArrayList<ByteBuffer>();

	public ArrayList<ByteBuffer> getBufferList() {
		return bufferList;
	}

	public void addVirtualSensor(VirtualSensor sensor) {
		sensors.add(sensor);
	}

	public boolean removeVirtualSensor(VirtualSensor sensor) {
		return sensors.remove(sensor);
	}

	public void setBufferList(ArrayList<ByteBuffer> bufferList) {
		this.bufferList = bufferList;
	}

	public Socket getSocket() {
		return this.socket;
	}

	public void close() {
		try {
			heartbeat.interrupt();
			socket.close();
			this.interrupt();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public boolean connect(String host, int port) {
		try {
			socket = new Socket(host, port);
			socket.setKeepAlive(true); // long connection
			socket.setSendBufferSize(16 * 1024);
			heartbeat = new HeartBeat(this);
			heartbeat.start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			System.out.println("Client cannot connect to Socket Server!");
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public void run() {
		if (!connect(host, port))
			return;
		try {
			OutputStream out = socket.getOutputStream();
			List<ByteBuffer> toBeSend = new LinkedList<ByteBuffer>();
			while (!socket.isClosed()) {
				synchronized (bufferList) {
					while (bufferList.isEmpty())
						bufferList.wait();
					int size = bufferList.size();
					for (int i = 0; i < size; i++) {
						toBeSend.add(bufferList.remove(0));
					}
				}
				for (int i = 0; i < toBeSend.size(); i++) {
					out.write(toBeSend.get(i).array());
				}
				toBeSend.clear();
			}
		} catch (InterruptedException e) {
			//e.printStackTrace();
		} catch (IOException e) {
			//e.printStackTrace();
		}

	}

	public ArrayList<VirtualSensor> getSensors() {
		return sensors;
	}
	
	

}
